﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MyLocalChurch.Models;
using MyLocalChurch.Models.Enumerations;
using MyLocalChurch.Models.KidsChurch;

namespace MyLocalChurch.Business
{
    public static class ReportManager
    {
        public static ReportSummary RetrieveReportSummary(MyContext context)
        {
            var summary = new ReportSummary();

            var churchServices = context.ChurchServices
                                        .Where(cs => cs.IsActive)
                                        .OrderBy(cs => cs.StartTime)
                                        .ToList();
            churchServices.ForEach(cs => summary.Rows.Add(
                new ReportSummaryRow
                    {
                        ChurchServiceId = cs.Id,
                        ChurchService = cs.StartTime
                    }));

            var kids = context.Kids.ToList();
            foreach (var kid in kids)
            {
                var kidCategory = KidManager.GetKidCategory(kid);

                foreach (var checkInOut in kid.CheckInOuts)
                {
                    var summaryRow = summary.Rows
                                            .FirstOrDefault(r => r.ChurchServiceId == checkInOut.ChurchService.Id);

                    if (summaryRow == null)
                        continue;

                    switch (kidCategory)
                    {
                        case KidCategory.Toddler:
                            summaryRow.TotalToddler++;
                            summary.TotalToddler++;

                            if (checkInOut.CheckOutTimeStamp.HasValue)
                            {
                                summaryRow.TotalToddlerCheckedOut++;
                                summary.TotalToddlerCheckedOut++;
                            }
                            break;
                        case KidCategory.PreSchool:
                            summaryRow.TotalPreSchool++;
                            summary.TotalPreSchool++;

                            if (checkInOut.CheckOutTimeStamp.HasValue)
                            {
                                summaryRow.TotalPreSchoolCheckedOut++;
                                summary.TotalPreSchoolCheckedOut++;
                            }
                            break;
                        case KidCategory.Primary:
                            summaryRow.TotalPrimary++;
                            summary.TotalPrimary++;

                            if (checkInOut.CheckOutTimeStamp.HasValue)
                            {
                                summaryRow.TotalPrimaryCheckedOut++;
                                summary.TotalPrimaryCheckedOut++;
                            }
                            break;
                        case KidCategory.PreTeen:
                            summaryRow.TotalPreTeen++;
                            summary.TotalPreTeen++;

                            if (checkInOut.CheckOutTimeStamp.HasValue)
                            {
                                summaryRow.TotalPreTeenCheckedOut++;
                                summary.TotalPreTeenCheckedOut++;
                            }
                            break;
                        default:
                            continue;
                    }

                    summaryRow.SubTotal++;
                    summary.GrandTotal++;

                    if (checkInOut.CheckOutTimeStamp.HasValue)
                    {
                        summaryRow.SubTotalCheckedOut++;
                        summary.GrandTotalCheckedOut++;
                    }
                }
            }

            return summary;
        }

        public static List<ReportDetail> RetrieveReportDetails(
            MyContext context,
            ChurchService churchService, ReportCategory category,
            DateTime? startDate, DateTime? endDate, bool checkedOutOnly)
        {
            var reportDetails = new List<ReportDetail>();

            var kids = context.Kids.ToList();
            foreach (var kid in kids)
            {
                var kidCategory = KidManager.GetKidCategory(kid);
                if (!(category == ReportCategory.All
                      || (category == ReportCategory.Toddler && kidCategory == KidCategory.Toddler)
                      || (category == ReportCategory.Primary && kidCategory == KidCategory.Primary)
                      || (category == ReportCategory.PreSchool && kidCategory == KidCategory.PreSchool)
                      || (category == ReportCategory.PreTeen && kidCategory == KidCategory.PreTeen)
                     ))
                    continue;

                var checkInOuts = checkedOutOnly
                                      ? kid.CheckInOuts.Where(c => c.CheckOutTimeStamp.HasValue)
                                      : kid.CheckInOuts;

                if (churchService != null)
                    checkInOuts = checkInOuts.Where(cs => cs.ChurchService == churchService);

                if (startDate.HasValue)
                    checkInOuts = checkInOuts.Where(c => startDate.Value.Date <= c.CheckInTimeStamp.Date);

                if (endDate.HasValue)
                    checkInOuts = checkInOuts.Where(c => c.CheckInTimeStamp.Date <= endDate.Value.Date);

                reportDetails.AddRange(
                    checkInOuts.Select(checkInOut => new ReportDetail
                        {
                            ChurchService = checkInOut.ChurchService.ToString(),
                            Category = KidManager.GetKidCategory(kid).ToString(),
                            Name = kid.ToString(),
                            CheckInTime = checkInOut.CheckInTimeStamp.ToString("g"),
                            CheckOutTime = checkInOut.CheckOutTimeStamp.HasValue
                                               ? checkInOut.CheckOutTimeStamp.Value.ToString("g")
                                               : string.Empty
                        }));
            }

            reportDetails.Sort();
            return reportDetails;
        }
    }
}